
package com.yuan.unit;

import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.geocoder.GeocodeAddress;
import com.yuan.control.CheckControl;
import com.yuan.control.leaveTypeManager;
import com.yuan.model.Config;
import com.yuan.model.M上班考勤表;
import com.yuan.model.M下班考勤表;
import com.yuan.model.M员工信息表;
import com.yuan.model.M员工活动轨迹表;
import com.yuan.model.M考勤表;
import com.yuan.model.M请假申请;
import com.yuan.model.Users;
import com.yuan.prefence.MsgKeys;

import android.content.Context;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.util.Pair;

import java.util.ArrayList;
import java.util.List;

/**
 * 异步线程处理类
 * 
 * @author YUAN
 */
public class AsyncDataJobHandler extends HandlerThread implements Handler.Callback
{
    private volatile static AsyncDataJobHandler sInstance;
    private final static String TAG = "AsyncDataJobHandler";

    private boolean isBindContext = false;
    private Context mContext;
    private Handler mHandler = null;
    private ArrayList<Pair<Integer, Message>> mQueuedMessages = null;

    public AsyncDataJobHandler(String name) {
        super(name);
        // TODO Auto-generated constructor stub
    }

    public AsyncDataJobHandler() {
        super(TAG + ": " + Long.toString(System.currentTimeMillis()));
        start();
        // TODO Auto-generated constructor stub
    }

    public void bindContext(Context c) {
        isBindContext = true;
        mContext = c;
    }

    public boolean isBindContext() {
        return isBindContext;
    }

    public void onDestroy() {
        // TODO Auto-generated method stub

    }

    /**
     * 从队列中取到相应的操作 并根据序号 发送到不同的switch case进行处理
     * 
     * @author YuanWei
     */
    @Override
    public boolean handleMessage(Message msg) {
        // TODO Auto-generated method stub
        Object object[] = null;
        Message reply = null;
        boolean flag;
        if (mContext == null) {
            BLog.d(TAG, "No context, quit handling job");
            return false;
        }
        switch (msg.what) {
            case MsgKeys.MSG_GETGPSFROMNAME:
                object = (Object[]) msg.obj;
                List<GeocodeAddress> listadress = MapHelper.getInstance().SearchGPSFromLocalName(
                        mContext,
                        (String) object[0], (String) object[2]);
                reply = new Message();
                reply.what = MsgKeys.MSG_GETGPSFROMNAME;
                reply.obj = listadress;
                ((Handler) object[1]).sendMessage(reply);
                object = null;
                reply = null;
                break;
            case MsgKeys.MSG_GETNAMEFROMGPS:
                object = (Object[]) msg.obj;
                String adress = MapHelper.getInstance().SearchLocalNameFromGPS(mContext,
                        (LatLonPoint) object[0]);
                reply = new Message();
                reply.what = MsgKeys.MSG_GETNAMEFROMGPS;
                reply.obj = adress;
                ((Handler) object[1]).sendMessage(reply);
                object = null;
                break;
            case MsgKeys.MSG_GETCONFIG:
                object = (Object[]) msg.obj;
                flag = Config.getInstance().getConfigFromNet(mContext);
                reply = new Message();
                reply.what = flag ? MsgKeys.MSG_GETCONFIGSESSED : MsgKeys.MSG_GETCONFIGFILED;
                ((Handler) object[1]).sendMessage(reply);
                object = null;
                break;
            case MsgKeys.LEAVETYPEFROMSQL:
                object = (Object[]) msg.obj;
                leaveTypeManager.initMarkSql(mContext);
                List<?> list = leaveTypeManager.queryMarkData(mContext);
                reply = new Message();
                reply.what = MsgKeys.LEAVETYPEFROMSQL;
                reply.obj = list;
                ((Handler) object[1]).sendMessage(reply);
                break;
            case MsgKeys.MSG_LOGIN:
                object = (Object[]) msg.obj;
                flag = Users.getInstance().login(mContext);
                reply = new Message();
                reply.what = flag ? MsgKeys.MSG_LOGINSESSED : MsgKeys.MSG_LOGINSFILED;
                ((Handler) object[1]).sendMessage(reply);
                if (flag)
                {
                    CheckControl.initUser();
                    GetUserInfo((Handler) object[1]);
                }
                object = null;
                break;
            case MsgKeys.GETUSERINFO:
                object = (Object[]) msg.obj;
                flag = M员工信息表.getInstance().getUserInfo(mContext);
                reply = new Message();
                reply.what = flag ? MsgKeys.GETUSERINFOSESSED : MsgKeys.GETUSERINFOFILED;
                ((Handler) object[1]).sendMessage(reply);
                CheckControl.init员工信息表(mContext);
                object = null;
                break;
            case MsgKeys.ASKFORLEAVE:
                object = (Object[]) msg.obj;
                flag = M请假申请.getInstance().askForLeave(mContext);
                reply = new Message();
                reply.what = flag ? MsgKeys.ASKFORLEAVESUCCEED : MsgKeys.ASKFORLEAVEFILDED;
                ((Handler) object[1]).sendMessage(reply);
                CheckControl.init请假申请();
                object = null;
                break;
            case MsgKeys.GETALLLEAVEACCOUNT:
                object = (Object[]) msg.obj;
                reply = new Message();
                flag = M请假申请.getInstance().getAllLeaveAccount(mContext);
                reply.what = flag ? MsgKeys.GETALLLEAVEACCOUNTSUCCEED
                        : MsgKeys.GETALLLEAVEACCOUNTFILED;
                ((Handler) object[1]).sendMessage(reply);
                object = null;
                break;
            case MsgKeys.CHECKIN:
                object = (Object[]) msg.obj;
                reply = new Message();
                flag = M上班考勤表.getInstance().checkIN(mContext);
                reply.what = flag ? MsgKeys.CHECKINSUCCEED : MsgKeys.CHECKINFILED;
                if (flag) {
                    CheckControl.init上班M考勤表();
                }
                ((Handler) object[1]).sendMessage(reply);
                object = null;
                break;
            case MsgKeys.CHECKOUT:
                object = (Object[]) msg.obj;
                reply = new Message();
                flag = M下班考勤表.getInstance().checkOUT(mContext);
                reply.what = flag ? MsgKeys.CHECKOUTSUCCEED : MsgKeys.CHECKOUTFILED;
                if (flag) {
                    CheckControl.init下班M考勤表();
                }
                ((Handler) object[1]).sendMessage(reply);
                object = null;
                break;
            case MsgKeys.UPDATELOCATION:
                M员工活动轨迹表.getInstance().updateLocation(mContext);
                break;
            case MsgKeys.CANCELLEAVE:
                object = (Object[]) msg.obj;
                reply = new Message();
                flag = M请假申请.getInstance().cancelLeave(mContext);
                reply.what = flag ? MsgKeys.CANCELLEAVESUCCEED : MsgKeys.CANCELLEAVEFILLED;
                ((Handler) object[1]).sendMessage(reply);
                object = null;
                break;
            case MsgKeys.GETMONTHCHECK:
                object = (Object[]) msg.obj;
                reply = new Message();
                flag = M考勤表.getInstance().getmonthcheck(mContext, (String) object[0]);
                reply.what = flag ? MsgKeys.GETMONTHCHECKSUCCEED : MsgKeys.GETMONTHCHECKFILLED;
                ((Handler) object[1]).sendMessage(reply);
                object = null;
                break;
            case MsgKeys.GETCHECK:
                object = (Object[]) msg.obj;
                reply = new Message();
                flag = M考勤表.getInstance().getcheck(mContext, (String) object[0]);
                reply.what = flag ? MsgKeys.GETCHECKSUCCEED : MsgKeys.GETCHECKFILLED;
                ((Handler) object[1]).sendMessage(reply);
                object = null;
                break;
            case MsgKeys.CHNAGEPWD:
                object = (Object[]) msg.obj;
                reply = new Message();
                flag = Users.getInstance().changepwd(mContext, (String) object[0]);
                reply.what = flag ? MsgKeys.CHNAGEPWDSUCCEED : MsgKeys.CHNAGEPWDFILLED;
                ((Handler) object[1]).sendMessage(reply);
                object = null;
                break;
            case MsgKeys.GETTRAIL:
                object = (Object[]) msg.obj;
                reply = new Message();
                flag = M员工活动轨迹表.getInstance().gettrail(mContext, (String) object[0]);
                reply.what = flag ? MsgKeys.GETTRAILSUCCEED : MsgKeys.GETTRAILFILLED;
                ((Handler) object[1]).sendMessage(reply);
                object = null;
                break;
            default:
                break;
        }
        return false;
    }

    @Override
    protected void onLooperPrepared() {
        synchronized (this) {
            mHandler = new Handler(this.getLooper(), this);
            if (mQueuedMessages != null) {
                for (Pair<Integer, Message> p : mQueuedMessages) {
                    mHandler.sendMessageDelayed(p.second, p.first.intValue());
                }
                mQueuedMessages.clear();
                mQueuedMessages = null;
            }
        }
    }

    public static AsyncDataJobHandler getInstance() {
        if (sInstance == null) {
            synchronized (AsyncDataJobHandler.class) {
                if (sInstance == null) {
                    sInstance = new AsyncDataJobHandler();
                }
            }
        }
        return sInstance;
    }

    /**
     * 将发送给来的操作放到mQueuedMessages队列中
     * 
     * @author YuanWei
     * @param what 操作编号
     * @param obj 操作需要的参数 为了普适性 设置为Object
     * @param delay 是否立即发送的队列中 delay为0立即发送到队列中 delay不为0时 延时发送 对于不紧急的需求可以延时发送
     */
    private final void sendMsg(int what, Object obj, int delay) {
        Message msg = new Message();
        msg.what = what;
        msg.obj = obj;
        synchronized (this) {
            if (mHandler == null) {
                if (mQueuedMessages == null) {
                    mQueuedMessages = new ArrayList<Pair<Integer, Message>>(5);
                }
                mQueuedMessages.add(new Pair<Integer, Message>(Integer.valueOf(delay), msg));
                return;
            }
        }
        if (delay != 0) {
            mHandler.sendMessageDelayed(msg, delay);
        } else {
            mHandler.sendMessage(msg);
        }
    }

    public void getGPSFromName(Handler replyTo, String adress, String city) {
        // TODO Auto-generated method stub
        sendMsg(MsgKeys.MSG_GETGPSFROMNAME, new Object[] {
                adress, replyTo, city
        }, 0);
    }

    public void getNameFromGPS(Handler replyTo, LatLonPoint point) {
        // TODO Auto-generated method stub
        sendMsg(MsgKeys.MSG_GETNAMEFROMGPS, new Object[] {
                point, replyTo
        }, 0);
    }

    public void getConfig(Handler replyTo) {
        // TODO Auto-generated method stub
        sendMsg(MsgKeys.MSG_GETCONFIG, new Object[] {
                " ",
                replyTo
        }, 0);
    }

    public void getLeaveType(Handler replyTo) {
        // TODO Auto-generated method stub
        sendMsg(MsgKeys.LEAVETYPEFROMSQL, new Object[] {
                " ",
                replyTo
        }, 0);
    }

    public void Login(Handler replyTo) {
        // TODO Auto-generated method stub
        sendMsg(MsgKeys.MSG_LOGIN, new Object[] {
                " ",
                replyTo
        }, 0);
    }

    public void GetUserInfo(Handler replyTo) {
        // TODO Auto-generated method stub
        sendMsg(MsgKeys.GETUSERINFO, new Object[] {
                " ",
                replyTo
        }, 0);
    }

    public void AskLeave(Handler replyTo) {
        // TODO Auto-generated method stub
        sendMsg(MsgKeys.ASKFORLEAVE, new Object[] {
                " ",
                replyTo
        }, 0);
    }

    public void getAllLeaveAccount(Handler replyTo) {
        // TODO Auto-generated method stub
        sendMsg(MsgKeys.GETALLLEAVEACCOUNT, new Object[] {
                " ",
                replyTo
        }, 0);
    }

    public void checkIn(Handler replyTo) {
        // TODO Auto-generated method stub
        sendMsg(MsgKeys.CHECKIN, new Object[] {
                " ",
                replyTo
        }, 0);
    }

    public void checkOut(Handler replyTo) {
        // TODO Auto-generated method stub
        sendMsg(MsgKeys.CHECKOUT, new Object[] {
                " ",
                replyTo
        }, 0);
    }

    public void updateLocation() {
        // TODO Auto-generated method stub
        sendMsg(MsgKeys.UPDATELOCATION, new Object[] {
                " "

        }, 0);
    }

    public void cancelLeave(Handler replyTo) {
        // TODO Auto-generated method stub
        sendMsg(MsgKeys.CANCELLEAVE, new Object[] {
                " ",
                replyTo
        }, 0);
    }

    public void getmonthcheck(Handler replyTo, String data) {
        // TODO Auto-generated method stub
        sendMsg(MsgKeys.GETMONTHCHECK, new Object[] {
                data,
                replyTo
        }, 0);
    }

    public void getcheck(Handler replyTo, String data) {
        // TODO Auto-generated method stub
        sendMsg(MsgKeys.GETCHECK, new Object[] {
                data,
                replyTo
        }, 0);
    }

    public void changepwd(Handler replyTo, String newpwd) {
        // TODO Auto-generated method stub
        sendMsg(MsgKeys.CHNAGEPWD, new Object[] {
                newpwd,
                replyTo
        }, 0);
    }

    public void gettrail(Handler replyTo, String date) {
        // TODO Auto-generated method stub
        sendMsg(MsgKeys.GETTRAIL, new Object[] {
                date,
                replyTo
        }, 0);
    }
}
